{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Modern C++\n",
    "\n",
    "[Microsoft: Welcome back to C++ - Modern C++](https://docs.microsoft.com/en-us/cpp/cpp/welcome-back-to-cpp-modern-cpp?view=vs-2019)\n",
    "\n",
    "One of the original requirements for C++ was **backward compatibility** with the C language. \n",
    "\n",
    "As a result, C++ has always permitted C-style programming, with raw pointers, arrays, null-terminated character strings, and other features. \n",
    "\n",
    "They may enable great performance, but can also **spawn bugs and complexity**\n",
    "\n",
    "The evolution of C++ has emphasized features that greatly reduce the need to use C-style idioms.\n",
    "\n",
    "From the advent of C++98 to the official finalization of C++11,it has accumulated over a decade. C++14/17 is an important complement and optimization for C++11,and C++20 brings this language to the door of **modernization**. \n",
    "\n",
    "* **Modern C++（C++11/14/17/20) code is simpler, safer, more elegant, and still as fast as ever.**\n",
    "\n",
    "The old C-programming facilities are there when you need them, but with modern C++ code you should need them less and less. \n",
    "\n",
    "![moderncpp](./img/cpp/moderncpp.png)\n",
    "\n",
    "\n",
    "**Reference**\n",
    "* Ivor Horton,Peter Van Weert: Beginning C++17:From Novice to Professional(Fifth Edition),Ivor Horton and Peter Van Weert,2018 \n",
    "\n",
    "  * Code: https://github.com/Apress/beg-cplusplus17\n",
    "\n",
    " \n",
    "\n",
    "**Modern C++ Similars of Python Tuple,List,Dict**\n",
    "\n",
    "| Python  |C++     |\n",
    "| ------- |:----------:|\n",
    "| tuple   | std::tuple|\n",
    "| list    | std::vectors |\n",
    "| dict    |  std::unordered_map |\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "## 1 std::tuple\n",
    "\n",
    "Python has had tuples pretty much since the beginning. \n",
    "\n",
    "C++ added `tuple` to the standard library in `C++11`. The proposal even mentions Python as an inspiration:\n",
    "\n",
    "tuple is a fixed-size collection of `heterogeneous` values.\n",
    "\n",
    "* `std::get`: Get the value of a position in the tuple\n",
    "\n",
    "* C++17, decompose a tuple into individual vars"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Writing ./demo/src/tuple.cpp\n"
     ]
    }
   ],
   "source": [
    "%%file ./demo/src/tuple.cpp\n",
    "#include <string>\n",
    "#include <iostream>\n",
    "#include <tuple>\n",
    "\n",
    "using namespace std;\n",
    "\n",
    "int main()\n",
    "{\n",
    "  tuple<int,string,float> tup{1,\"str2\",3.21};\n",
    "  cout << get<0>(tup)<<\" \"<<get<1>(tup)<<endl;\n",
    "  // C++17, decompose a tuple into individual vars\n",
    "  auto [a, b, c] = tup;\n",
    "  cout << a << \", \" << b << \", \" << c << \"\\n\";\n",
    "  return 0;\n",
    "}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "!g++ -std=c++17 -o ./demo/bin/tuple ./demo/src/tuple.cpp"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "1 str2\n",
      "1, str2, 3.21\n"
     ]
    }
   ],
   "source": [
    "!.\\demo\\bin\\tuple"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### -std=standard\n",
    " \n",
    "To select C++ standard in GCC,use the option\n",
    "\n",
    "```\n",
    "-std=standard \n",
    "```\n",
    "\n",
    "The default standard  for GCC 6.1 and above is **-std=gnu++14**\n",
    "\n",
    "You can use command-line flag `-std` to explicitly specify the C++ standard. For example,\n",
    "\n",
    "* -std=c++98, or -std=gnu++98 (C++98 with GNU extensions)\n",
    "* -std=c++11, or -std=gnu++11 (C++11 with GNU extensions)\n",
    "* -std=c++14, or -std=gnu++14 (C++14 with GNU extensions), **default mode for GCC 6.1 and above**.\n",
    "* -std=c++17, or -std=gnu++17 (C++17 with GNU extensions), experimental.\n",
    "* -std=c++2a, or -std=gnu++2a (C++2a with GNU extensions), experimental.\n",
    "```\n",
    "\n",
    "[The GNU Project:](https://www.gnu.org/) GNU is a Unit-like operating system that is free software—that is, it respects users' freedom.\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Uniform initialization\n",
    "```cpp\n",
    "tuple<int,string,float> tup{1,\"str2\",3.21};\n",
    "```\n",
    "In modern C++, you can use `brace{} initialization for any type`.\n",
    "```\n",
    "int i{10};\n",
    "```\n",
    "This form of initialization is especially convenient when initializing `arrays, vectors, or other containers`. "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### auto instead of explicit type names\n",
    "```cpp\n",
    "auto [a, b, c] = tup;\n",
    "``` \n",
    "C++11 introduced the `auto` keyword for use in `variable, function, and template declarations`. \n",
    "\n",
    "`auto` tells the compiler to `deduce the type of the object from its initialization expression.` so that you don't have to type it explicitly. \n",
    "\n",
    "```cpp\n",
    "int j = 0;  // Variable j is explicitly type int.\n",
    "auto k = 0; // Variable k is implicitly type int because 0 is an integer.\n",
    "```"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 2 std::vectors\n",
    "\n",
    " std::vectors \n",
    "\n",
    "`Vectors` are `sequence containers` representing arrays that can `change in size`.\n",
    "\n",
    "`std::vectors`has features similar to Python lists. Which data structure you want to choose depends on your requirements.\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Writing ./demo/src/vector.cpp\n"
     ]
    }
   ],
   "source": [
    "%%file ./demo/src/vector.cpp\n",
    "#include <iostream>\n",
    "#include <vector>\n",
    "\n",
    "using namespace std;\n",
    "\n",
    "int main()\n",
    "{\n",
    "    vector<int> myList;\n",
    "    for(int i = 0; i < 10; i++)\n",
    "        myList.push_back(i);\n",
    "    cout <<myList[2]<<endl; \n",
    "    \n",
    "    for (auto &item : myList)\n",
    "        cout << item << \" \";\n",
    "    cout << endl;\n",
    "}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": [
    "!g++  -o ./demo/bin/vector ./demo/src/vector.cpp"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "2\n",
      "0 1 2 3 4 5 6 7 8 9 \n"
     ]
    }
   ],
   "source": [
    "!.\\demo\\bin\\vector"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Range-based for loops\n",
    "\n",
    "`C-style iteration` over arrays and containers is prone to `indexing errors` and is also `tedious to type`.\n",
    "```cpp\n",
    "for(int i = 0; i < 10; i++)\n",
    "        myList.push_back(i);\n",
    "```\n",
    "To eliminate these errors, and make your code more readable, use `range-based for loops` with both Standard Library containers and raw arrays. \n",
    "\n",
    "```cpp\n",
    "for (auto &item : myList)\n",
    "        cout << item << \" \";\n",
    "```\n",
    "\n",
    ">Ref:[Using std::vector and std::string to read CSV files](http://localhost:8890/notebooks/Unit8-4-Python-C-API.ipynb)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 3 std::unordered_map\n",
    "\n",
    "The closest match in `C++` would be an \n",
    "\n",
    "```cpp\n",
    "std::unordered_map<key type, value type>\n",
    "```\n",
    "\n",
    "`Unordered map` is an `associative container` that contains key-value pairs with `unique` keys.\n",
    "\n",
    "This is a` hash` table mapping `keys` to `values`.\n",
    "\n",
    "Search, insertion, and removal of elements have average constant-time complexity.\n",
    "\n",
    "### 3.1 C++11\n",
    "\n",
    "The values have the same type of integer\n",
    "\n",
    "```cpp\n",
    "   unordered_map<string, int> dishes = {{\"eggs\",  2}, {\"sausage\", 1},{ \"bacon\", 1 }, {\"spam\", 500}}\n",
    "```"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Writing ./demo/src/dict.cpp\n"
     ]
    }
   ],
   "source": [
    "%%file ./demo/src/dict.cpp\n",
    "#include <string>\n",
    "#include <iostream>\n",
    "#include <unordered_map>\n",
    "\n",
    "using namespace std;\n",
    "\n",
    "int main()\n",
    "{\n",
    "   unordered_map<string, int> dishes = {{\"eggs\",  2}, {\"sausage\", 1},{ \"bacon\", 1 }, {\"spam\", 500}};\n",
    "   cout << dishes[\"eggs\"] << endl; \n",
    "   for(auto &it: dishes){\n",
    "        cout<<\"key = \"<<it.first<<\" value = \"<<it.second<<endl;\n",
    "   }\n",
    "   return 0; \n",
    "}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [],
   "source": [
    "!g++ -o  ./demo/bin/dict ./demo/src/dict.cpp"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "2\n",
      "key = spam value = 500\n",
      "key = bacon value = 1\n",
      "key = sausage value = 1\n",
      "key = eggs value = 2\n"
     ]
    }
   ],
   "source": [
    "!.\\demo\\bin\\dict"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 3.2  C++17 `any`\n",
    "\n",
    "The values have the different types\n",
    "\n",
    "`any` is one of the newest features of C++17 that provides a type-safe container to store single value of any type.\n",
    "```cpp\n",
    "unordered_map<string, any> student = {{\"name\", \"zhangshan\"}, {\"age\", 20}};\n",
    "```"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Writing ./demo/src/dictany.cpp\n"
     ]
    }
   ],
   "source": [
    "%%file ./demo/src/dictany.cpp\n",
    "#include <string>\n",
    "#include <iostream>\n",
    "#include <unordered_map>\n",
    "#include <any>\n",
    "\n",
    "using namespace std;\n",
    "\n",
    "int main()\n",
    "{\n",
    "   unordered_map<string, any> student = {{\"name\", \"zhangshan\"}, {\"age\", 20}};\n",
    "   cout << any_cast<const char *>(student[\"name\"]) << endl;\n",
    "   cout << any_cast<int>(student[\"age\"]) << endl;\n",
    "   return 0;\n",
    "}\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [],
   "source": [
    "!g++ -std=c++17 -o  ./demo/bin/dictany ./demo/src/dictany.cpp"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "zhangshan\n",
      "20\n"
     ]
    }
   ],
   "source": [
    "!.\\demo\\bin\\dictany"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": []
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Further Reading\n",
    "\n",
    "\n",
    "The SimVCCE is the vapor-compression refrigeration cycle steady-state simulator in Python, C++ and Modelica\n",
    "\n",
    "* https://github.com/PySEE/SimVCCE\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3.8.7 64-bit",
   "name": "python387jvsc74a57bd02db524e06e9f5f4ffedc911c917cb75e12dbc923643829bf417064a77eb14d37"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.8.7"
  },
  "latex_envs": {
   "LaTeX_envs_menu_present": true,
   "autoclose": false,
   "autocomplete": true,
   "bibliofile": "biblio.bib",
   "cite_by": "apalike",
   "current_citInitial": 1,
   "eqLabelWithNumbers": true,
   "eqNumInitial": 1,
   "hotkeys": {
    "equation": "Ctrl-E",
    "itemize": "Ctrl-I"
   },
   "labels_anchors": false,
   "latex_user_defs": false,
   "report_style_numbering": false,
   "user_envs_cfg": false
  },
  "toc": {
   "base_numbering": 1,
   "nav_menu": {},
   "number_sections": false,
   "sideBar": true,
   "skip_h1_title": false,
   "title_cell": "Table of Contents",
   "title_sidebar": "Contents",
   "toc_cell": false,
   "toc_position": {
    "height": "calc(100% - 180px)",
    "left": "10px",
    "top": "150px",
    "width": "165px"
   },
   "toc_section_display": true,
   "toc_window_display": true
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
